<template>
  <div class="container">
    <div
        class="component"
    >
      <div class="search top-card">
        <div>
          <el-input
              v-model="searchForm.name"
              @keyup.enter.native="companySearch"
              @change="companySearch"
              placeholder="请输入门店名称"
              clearable
          ></el-input>
        </div>
        <div>
          <el-input
              v-model="searchForm.code"
              @keyup.enter.native="companySearch"
              @change="companySearch"
              placeholder="请输入门店编码"
              clearable
          ></el-input>
        </div>
        <div style="width: 180px">
          <el-select
              v-model="searchForm.tag"
              placeholder="请选择门店标签"
              @change="companySearch"
              clearable
          >
            <el-option
                v-for="item in companyTag"
                :key="item.value"
                :label="item.name"
                :value="item.value"
            >
            </el-option>
          </el-select>
        </div>
        <div>
          <el-button
              type="primary"
              size="mini"
              @click="companySearch"
          >
            <el-icon class="margin-right-xs"><Search /></el-icon>
            查询
          </el-button>
          <el-button
              size="mini"
              @click="companySearch"
          >
            <el-icon class="margin-right-xs"><Refresh /></el-icon>
            重置
          </el-button>
          <el-button
              size="mini"
              @click="showDesc = !showDesc"
          >
            <el-icon class="margin-right-xs"><ChatRound /></el-icon>
            说明
          </el-button>
        </div>
      </div>
      <div class="margin-top">
        <!-- 级联区域 -->
        <div class="flex align-center box-wrapper">
          <div
              v-for="(node, nodeIndex) in organizeData"
              :key="nodeIndex"
          >
            <div v-if="node.length" class="box">
              <div class="fixed-top">
                {{ indexOption[nodeIndex + 1] ? indexOption[nodeIndex + 1] : nodeIndex + 1 }}级组织{{ nodeIndex === 0 ? '' :
                  '及门店' }}
                <div v-if="!readonly">
                <span
                    @click="checkSonOrgOrCompany(node, nodeIndex, true)"
                    class="text-blue cursor-pointer no-shrink margin-right-xs"
                >全选</span>
                <span
                    @click="checkSonOrgOrCompany(node, nodeIndex, false)"
                    class="text-blue cursor-pointer no-shrink"
                >全不选</span>
                </div>
              </div>
              <div class="node-wrapper">
                <div
                    class="node_item cursor-style"
                    v-for="item in node"
                    :key="item.id"
                >
                  <div
                      class="flex align-center justify-between margin-top-xs"
                      :class="{ 'text-blue': item.clicked }"
                  >
                    <div class="flex align-center flex-sub" style="width: 61%">
                      <el-checkbox
                          @change="checkChange(item, $event)"
                          :disabled="item.disabled || readonly"
                          v-model="item.checked"
                          :class="{ 'vir-check': item.disabled }"
                      ></el-checkbox>
                      <div
                          @click.stop="loadCompany(item, nodeIndex)"
                          class="flex-sub flex align-center"
                          style="width: 100%"
                      >
                        <el-icon v-if="item.nodeType === 'org'" class="margin-left-xs text-orange" style="margin-top: 2px">
                          <OfficeBuilding />
                        </el-icon>
                        <el-icon v-else class="margin-left-xs text-olive" style="margin-top: 2px">
                          <House />
                        </el-icon>
                        <el-tooltip
                            effect="light"
                            placement="top"
                            :content="`${item.name}${item.nodeType === 'org' ? '(' + item.storeNum + ')' : ''}`"
                        >
                          <div
                              class="margin-left-xs cursor-pointer text-cut"
                              style="width: 85%"
                          >
                            {{ item.name }}{{ item.nodeType === 'org' ? '(' + item.storeNum + ')' : '' }}
                          </div>
                        </el-tooltip>
                      </div>
                    </div>
                    <el-icon
                        @click.stop="loadCompany(item, nodeIndex)"
                        v-if="item.nodeType === 'org' && originData.filter(o => o.parentId === item.id).length"
                        class="cursor-pointer"
                        style="margin-top: 2px"
                    >
                      <ArrowRightBold />
                    </el-icon>
                  </div>
                </div>
              </div>
            </div>
            <div
                v-else
                class="node_item box flex align-center justify-center"
            >
              暂无数据
            </div>
          </div>

          <!--  筛选到的门店    -->
          <div class="box search-company-wrapper relative">
            <div class="fixed-top flex justify-between">
              查询门店结果
              <div v-if="!readonly">
              <span
                  @click="selectAllCompany(true)"
                  class="text-blue cursor-pointer"
              >全选</span>
                <span
                    @click="selectAllCompany(false)"
                    class="text-blue cursor-pointer"
                >全不选</span>
              </div>

              <span
                  v-if="!readonly"
                  @click="clearCompany"
                  class="text-red cursor-pointer"
              >清空</span>
            </div>
            <div class="node-wrapper">
              <el-tag
                  v-for="(item, index) in companyList"
                  :key="index"
                  size="small"
                  closable
                  @close="deleteCompanyTag(item)"
                  class="margin-left-xs margin-tb-xs"
              >
                <el-checkbox
                    v-model="item.checked"
                    @change="checkCompanyChange(item, $event)"
                    :disabled="readonly"
                ></el-checkbox>
                <el-tooltip
                    effect="light"
                    placement="top"
                    :content="`${item.name}【${item.code}】`"
                    v-if="item.name.length + item.code.length > 17"
                >
                <span>
                  {{ item.name.substr(0, 8) }}{{ item.name.length > 8 ? '...' : '' }}
                  【{{ item.code.substr(0, 7) }}{{ item.code.length > 7 ? '...' : '' }}】
                </span>
                </el-tooltip>
                <span v-else>
                {{ item.name }}
              </span>
              </el-tag>
              <div
                  class="company_footer"
                  v-if="companyList.length"
              >
                <el-pagination
                    @current-change="handleCompanyPageChange"
                    :current-page="searchForm.pageNum"
                    :page-size="searchForm.pageSize"
                    layout="total, prev, pager, next"
                    :total="companyListTotal"
                    :pager-count="5"
                    small
                >
                </el-pagination>
              </div>
            </div>
          </div>
        </div>
        <!--  已选择  -->
        <div
            class="checked_box"
            :style="{ width: organizeData.length * 250 + 280 + 'px' }"
        >
          <div class="flex justify-between align-center fixed-top">
            <span>已选{{ checkedCompanyOrOrgs.length }}个门店或组织</span>
            <span
                @click="clearChecked"
                class="text-red cursor-pointer"
                v-if="!readonly"
            >清空已选</span>
          </div>
          <div class="node-wrapper">
            <el-tag
                v-for="(item, index) in checkedCompanyOrOrgs"
                :key="index"
                size="small"
                :closable="!readonly"
                :type="item.nodeType === 'company' || item.nodeType === 'filterCompany' ? '' : 'warning'"
                @close="deleteChecked(item)"
                class="margin-left-xs margin-top-xs"
            >
              {{ item.name }}
            </el-tag>
          </div>
        </div>
      </div>
    </div>
    <div class="text-gray" v-if="showDesc">
      <p>背景：</p>
      <p>1.每一层级都会有门店的情况 </p>
      <p>2.选择上层的组织，下层的所有组织和门店不允许勾选（如果带上了，后台会重复下发）</p>
      <p>3.附带查询门店区域，查询出来的门店可供选择</p>
      <p>其他</p>
      <p>1.还有下层组织的组织需要显示向右箭头。2.点击组织是加载组织下的门店，点击勾选框才为选中。3.可根据关键词查询门店进行勾选。</p>
    </div>
  </div>

</template>

<script>
import {getAllOrgnize, getCompany, getCompanyByOrg} from '@/api/index.ts';
import {Refresh, Search} from '@element-plus/icons-vue';

export default {
  components: {Refresh, Search},
  props: ['echoData', 'readonly'],
  data() {
    return {
      originData: [],
      organizeData: [],
      checkedCompanyOrOrgs: [],
      searchForm: {
        name: '',
        code: '',
        tag: '',
        pageNum: 1,
        pageSize: 40
      },
      companyTag: [],
      companyList: [],
      companyListTotal: 0,
      indexOption: { 1: '一', 2: '二', 3: '三', 4: '四', 5: '五', 6: '六', 7: '七' },
      showDesc: false
    };
  },
  watch: {
    echoData: {
      immediate: true,
      handler() {
        this.echo();
      }
    },
    checkedCompanyOrOrgs(newVal) {
      this.companyList.forEach(comp => {
        let index = newVal.findIndex(item => item.id === comp.id);
        comp.checked = index > -1;
      });
    }
  },
  created() {
    this.getAllOrganize();
    this.getCompanyTags();
  },
  methods: {
    async getAllOrganize() {
      let res = await getAllOrgnize();
      let data = res.data;
      console.log(data);
      const firstData = [];
      data.forEach(item => {
        // 树勾选回显
        if (this.echoData && this.echoData.length) {
          let filter = this.echoData.filter(d => d.assertId === item.id);
          item.checked = !!filter.length;
        } else {
          item.checked = false;
        }
        item.disabled = false;
        item.nodeType = 'org';
        if (item.parentId === '0') {
          item.level = 1;
          firstData.push(item);
        }
      });
      this.originData = data;
      this.organizeData.push(firstData);
    },
    // 回显
    echo() {
      this.checkedCompanyOrOrgs = [];
      this.originData.forEach(item => {
        if (this.echoData && this.echoData.length) {
          let filter = this.echoData.filter(d => d.assertId === item.id);
          item.checked = !!filter.length;
        } else {
          item.checked = false;
        }
      });
      if (this.echoData && this.echoData.length) {
        this.echoData.forEach(item => {
          this.checkedCompanyOrOrgs.push({
            name: item.assertName,
            id: item.assertId,
            nodeType: item.assertType === 1 ? 'org' : 'company'
          });
        });
      }
    },
    // 门店筛选区---------start
    getCompanyList() {
      let res = getCompany(this.searchForm);
      this.companyList = res.data.map(item => {
        let filter = [];
        if (this.checkedCompanyOrOrgs && this.checkedCompanyOrOrgs.length) {
          filter = this.checkedCompanyOrOrgs.filter(d => d.id === item.id);
        }
        return {
          ...item,
          checked: !!filter.length,
          nodeType: 'filterCompany'
        };
      });
      this.companyListTotal = Number(res.total);
    },
    companySearch() {
      this.searchForm.pageNum = 1;
      this.getCompanyList();
    },
    getCompanyTags() {
      this.companyTag = [
        {
          name: '测试标签1',
          value: '1'
        },
        {
          name: '测试标签2',
          value: '2'
        }  
      ];
    },
    checkCompanyChange(company, val) {
      if (val) {
        if (!this.checkedCompanyOrOrgs.find(item => item.id === company.id)) {
          this.checkedCompanyOrOrgs.push(company);
        }
      } else {
        this.checkedCompanyOrOrgs = this.checkedCompanyOrOrgs.filter(check => check.id !== company.id);
      }
    },
    selectAllCompany(flag) {
      if (flag) {
        this.companyList.forEach(item => {
          item.checked = true;
          if (!this.checkedCompanyOrOrgs.find(checked => checked.id === item.id)) {
            this.checkedCompanyOrOrgs.push(item);
          }
        });
      } else {
        this.companyList.forEach(item => {
          item.checked = false;
          this.checkedCompanyOrOrgs = this.checkedCompanyOrOrgs.filter(checked => checked.id !== item.id);
        });
      }
    },
    deleteCompanyTag(ele) {
      this.companyList = this.companyList.filter(c => c.id !== ele.id);
    },
    clearCompany() {
      this.companyList = [];
    },
    handleCompanyPageChange(val) {
      this.searchForm.pageNum = val;
      this.getCompanyList();
    },
    // 门店筛选区---------end
    loadData(item, index) {
      if (this.organizeData.length > index) {
        this.organizeData.splice(index + 1, this.organizeData.length - (index + 1));
      }
      let filters = this.originData.filter(o => o.parentId === item.id);
      filters.forEach(f => { f.level = item.level + 1 });
      this.organizeData.push(filters);
      // 添加层级时 判断父级选用情况
      this.setDisabled(item);
    },
    loadCompany(org, index) {
      if (org.nodeType === 'company') {
        if (this.readonly) { return }
        // 直接选中这一条
        this.checkChange(org, !org.checked);
        org.checked = !org.checked;
        return;
      }
      // 高亮点击过的zuz
      this.organizeData[index].forEach(o => {
        if (o.id === org.id) {
          o.clicked = true;
        } else {
          o.clicked = false;
        }
      });
      // 从下一层级重新渲染
      console.log('index ', index);
      console.log('this.organizeData ', this.organizeData);
      if (this.organizeData.length > index) {
        this.organizeData.splice(index + 1, this.organizeData.length - (index + 1));
      }
      let orgs = this.originData.filter(o => o.parentId === org.id);
      let data = getCompanyByOrg(org.id)
      console.log('getCompanyByOrg ', data);
      let results = [];
      data.forEach(item => {
        // 树勾选回显
        if (this.echoData && this.echoData.length) {
          let filter = this.echoData.filter(d => d.assertId === item.id);
          item.checked = !!filter.length;
        } else {
          item.checked = false;
        }
        item.disabled = false;
        item.nodeType = 'company';
        item.parentId = org.id;
        item.level = org.level + 1;
        results.push(item);
      });
      this.organizeData.push([...orgs, ...results]);
      this.setDisabled(org);
    },
    setDisabled(item) {
      // 获取所有后代节点
      let laterArr = this.findDescendantsWithAncestorId(this.organizeData, item.id).filter(f => f.id !== item.id);
      // 1.对所有后代节点 禁用勾选 操作
      this.organizeData.forEach(org => {
        if (org.length) {
          org.forEach(node => {
            laterArr.length && laterArr.forEach(l => {
              if (node.id === l.id) {
                if (item.checked || item.disabled) {
                  node.disabled = true;
                  node.checked = false;
                  // 去除已选择
                  this.checkedCompanyOrOrgs = this.checkedCompanyOrOrgs.filter(c => c.id !== node.id);
                } else {
                  node.disabled = false;
                }
              }
            });
          });
        }
      });
    },
    findDescendantsWithAncestorId(data2D, ancestorId) {
      let data = data2D.flat();
      const elementMap = new Map(data.map(item => [item.id, item]));
      // 检查一个元素是否是目标ID的后代
      function isDescendantOf(itemId, targetId) {
        let currentId = itemId;
        while (currentId !== '0' && elementMap.has(currentId)) {
          if (currentId === targetId) {
            return true;
          }
          currentId = elementMap.get(currentId).parentId;
        }
        return false;
      }
      // 收集所有符合条件的元素
      const result = data.filter(item => isDescendantOf(item.id, ancestorId));
      return result;
    },
    // 级联区域勾选
    checkChange(item, checked) {
      // 使用对象存储已选中的 id，提高查找效率
      const checkedIds = this.checkedCompanyOrOrgs.reduce((acc, cur) => {
        acc[cur.id] = true;
        return acc;
      }, {});
      if (checked) {
        if (!checkedIds[item.id]) { // 避免重复添加
          this.checkedCompanyOrOrgs.push(item);
          checkedIds[item.id] = true; // 更新 checkedIds
        }
      } else {
        // 删除元素
        if (checkedIds[item.id]) {
          this.checkedCompanyOrOrgs = this.checkedCompanyOrOrgs.filter(c => c.id !== item.id);
          delete checkedIds[item.id]; // 清除 checkedIds 中的记录
        }
      }
      this.setDisabled(item);
    },
    // 已选区删除
    deleteChecked(item) {
      // 右侧去除
      this.checkedCompanyOrOrgs = this.checkedCompanyOrOrgs.filter(c => c.id !== item.id);
      if (item.nodeType === 'filterCompany') {
        // 筛选的门店
        this.companyList.forEach(c => {
          if (c.id === item.id) {
            c.checked = false;
          }
        });
      } else {
        // 左侧取消勾选
        this.organizeData.forEach(o => {
          if (o.length) {
            o.forEach(i => {
              if (i.id === item.id) {
                i.checked = false;
              }
            });
          }
        });
      }
    },
    clearChecked() {
      this.checkedCompanyOrOrgs = [];
      this.organizeData.forEach(o => {
        if (o.length) {
          o.forEach(i => {
            i.checked = false;
            i.disabled = false;
          });
        }
      });
      // 筛选区也需要清空勾选
      this.companyList.forEach(item => { item.checked = false });
    },
    // 全选 全不选
    checkSonOrgOrCompany(node, nodeIndex, selectAll) {
      // node一定有长度
      if (nodeIndex > 0) {
        let filter = this.organizeData[nodeIndex - 1].filter(item => item.id === node[0].parentId);
        if (filter.length) {
          if (filter[0].checked) {
            return;
          }
        }
      }
      this.organizeData[nodeIndex].forEach(ele => {
        ele.checked = selectAll;
        if (selectAll) {
          if (!this.checkedCompanyOrOrgs.find(item => item.id === ele.id)) {
            this.checkedCompanyOrOrgs.push(ele);
          }
        } else {
          this.checkedCompanyOrOrgs = this.checkedCompanyOrOrgs.filter(c => c.id !== ele.id);
        }
      });
      // 需要改变下一级的是否可选择的状态
      if (this.organizeData[nodeIndex + 1] && Array.isArray(this.organizeData[nodeIndex + 1])) {
        this.organizeData[nodeIndex + 1].forEach(item => {
          item.checked = false;
          item.disabled = selectAll;
        });
      }
    }
  }
};
</script>

<style scoped lang="scss">
.container {
  width: 100%;
  height: 100%;
  padding: 20px;
  background-color: #ffffff;

  .text-orange {
    color: #f37b1d !important;
  }
  .text-olive {
    color: #8dc63f !important;
  }

  .component {

    .search {
      display: flex;
      gap: 0 10px;

      .ipt {
        width: 200px;

        :deep(.el-input__inner) {
          height: 30px;
          line-height: 30px;
        }
      }
    }

    .box-wrapper {
      overflow-x: auto;

      .box {
        width: 250px;
        height: 320px;
        border: 1px solid #e1dede;
        padding: 5px;
        flex-shrink: 0;
        position: relative;
        padding: 30px 0 10px 10px;

        &.search-company-wrapper {
          width: 280px;
        }

        &:first-child {
          border-radius: 8px 0 0 0;
        }

        &:last-child {
          border-radius: 0 8px 0 0;
        }

        &:not(:last-child) {
          border-right: 0;
        }

        .node_item {
          padding: 3px;
        }

        .fixed-top {
          position: absolute;
          width: calc(100% - 20px);
          top: 0;
          left: 15px;
          padding-top: 8px;
          background: #fff;
          display: flex;
          justify-content: space-between;
        }

        .node-wrapper {
          overflow-y: auto;
          overflow-x: hidden;
          height: 100%;

          &:has(.company_footer) {
            padding-bottom: 20px;
          }
        }
        /* 定义滚动条的宽度 */
        .node-wrapper::-webkit-scrollbar {
          width: 4px; /* 滚动条的宽度 */
        }

        /* 滑块的背景颜色和圆角 */
        .node-wrapper::-webkit-scrollbar-thumb {
          background-color: #888; /* 滑块的颜色 */
          border-radius: 10px; /* 圆角程度 */
        }

        /* 当鼠标悬停在滑块上时改变颜色 */
        .node-wrapper::-webkit-scrollbar-thumb:hover {
          background-color: #555; /* 鼠标悬停时滑块的颜色 */
        }

        /* 轨道的样式 */
        .node-wrapper::-webkit-scrollbar-track {
          background: #f1f1f1; /* 轨道的颜色 */
          border-radius: 10px; /* 圆角程度，与滑块一致 */
        }

        /* 可选：当滚动条出现但没有激活时的轨道颜色 */
        .node-wrapper::-webkit-scrollbar-track-piece:end {
          background: #f1f1f1;
          margin-bottom: 4px; /* 与滚动条宽度匹配 */
        }

        .company_footer {
          position: absolute;
          bottom: 0;
          background: #fff;
          left: 0;
          right: 0;
          z-index: 100;
        }
      }
    }


    .checked_box {
      max-width: 100%;
      height: 150px;
      border: 1px solid #e1dede;
      margin-top: -1px;
      padding: 30px 10px 10px 10px;
      border-radius: 0 0 8px 8px;
      position: relative;

      .fixed-top {
        position: absolute;
        width: calc(100% - 20px);
        top: 10px;
        left: 10px;
        background: #fff;
      }

      .node-wrapper {
        height: 120px;
        overflow: auto;
      }
    }
  }

  :deep(.el-checkbox__input.is-checked .el-checkbox__inner,
.el-checkbox__input.is-disabled.is-checked .el-checkbox__inner) {
    background-color: #409EFF;
    border-color: #409EFF;
  }

  :deep(.vir-check) {
    .el-checkbox__inner:after {
      transform: rotate(45deg) scaleY(1);
    }

  }
}

</style>
